#!/usr/bin/env python
# -*- coding: utf-8 -*-
# © Ethan Tan

from google.appengine.ext import db
from google.appengine.ext import blobstore
from google.appengine.api import users
from google.appengine.api import memcache

import os
import Cookie
import time
import random

RAND_LETTERS = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
           "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
           "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6",
           "7", "8", "9"]
def get_all_rights():
    return {
        'admin': False,
        'upload_pictures': False,
        'edit_pictures': False,
        'browse_albums': False  
        }
def detect_mime_from_image_data(image):
    if image[1:4] == 'PNG': return 'image/png'
    if image[0:3] == 'GIF': return 'image/gif'
    if image[6:10] == 'JFIF': return 'image/jpeg'
    return None

def get_counter(name):
    counter = Counter.get_by_key_name(name)
    if counter is None:
        counter = Counter(key_name=name, count=0)
    return counter

def get_service_user(user):
    if user is None:
        return None
    
    u = ServiceUser.get_by_key_name(user.user_id())
    if u is None:
        upload_token = "".join([random.choice(RAND_LETTERS) for x in range(20)])
        u = ServiceUser(key_name=user.user_id(), upload_token=upload_token, user=user, rights=["browse_albums"])
        u.put()
        
    return u
    
class ServiceUser(db.Model):
    user = db.UserProperty()
    upload_token = db.StringProperty()
    rights = db.StringListProperty()
    
class Counter(db.Model):
    count = db.IntegerProperty()

class Album(db.Model):
    name = db.StringProperty()
    creator = db.UserProperty()
    created_date = db.DateTimeProperty(auto_now_add=True)
    #pics_count = db.IntegerProperty(0)

class Khokng(db.Model):
    choanmiann = db.StringProperty() # full name
    nihun = db.StringProperty() # year
    hothau = db.StringProperty() # code
    tengte = db.IntegerProperty() # class
    khochhi = db.StringProperty() # examset
    choopiat = db.StringProperty() # category
    khobok = db.StringProperty() # subject

class Tebok(db.Model):
    choanmiann = db.StringProperty() # full name
    nihun = db.StringProperty() # year
    hothau = db.StringProperty() # code
    tengte = db.IntegerProperty() # class
    khochhi = db.StringProperty() # examset
    choopiat = db.StringProperty() # category
    khobok = db.StringProperty() # subject
    thauhang = db.TextProperty()#required=True) # content
    tootoo = db.BlobProperty() # figure
    toeho = db.StringProperty() # index
    tiamsoo = db.IntegerProperty() # points
    khamho = db.StringProperty() # unique ID of question
    khokng = db.ReferenceProperty(Khokng)

class Picture(db.Model):
    submitter = db.UserProperty()
    submitted_date = db.DateTimeProperty(auto_now_add=True)
    title = db.StringProperty()
    tags = db.StringListProperty()
    filesize = db.IntegerProperty()
    data = blobstore.BlobReferenceProperty()
    width = db.IntegerProperty()
    height = db.IntegerProperty()
    thumbnail_data = db.BlobProperty()
    content_type = db.StringProperty()
    album = db.ReferenceProperty(Album, collection_name='pictures')
    
class SessionData(db.Expando):
    user = db.UserProperty()

class MicroSession:
    COOKIE_NAME = "picsteak_microsession"
    
    def __init__(self):
        string_cookie = os.environ.get(u"HTTP_COOKIE", u"")
        cookie = Cookie.SimpleCookie()
        self.session_id = None
        
        if string_cookie != "":
            cookie.load(string_cookie)
            # find our session id
            cookie_value = cookie.get(self.COOKIE_NAME)
            if cookie_value is not None:
                self.session_id = cookie_value.value
            
        if self.session_id is None:
            # gen new session id
            rand_set = "".join([random.choice(RAND_LETTERS) for x in range(20)])
            self.session_id = "%s-%s" % ( int(time.time()), rand_set ) 
        
        send_cookie = True
        
        if send_cookie:
            # put http session header
            out_cookie = Cookie.SimpleCookie()
            out_cookie[self.COOKIE_NAME] = self.session_id
            print out_cookie.output()
        
        
class SessionNameError(Exception): pass
class SessionValueNotFoundError(Exception): pass

class Session:
    """
    Class Session represents session data storage and takes care on 
    sessions/cookies
    """
    COOKIE_NAME = "picsteak_session"
    MEMCACHE_STORE_TIME = 3600 # in seconds
    
    session_data = None
    
    def __init__(self):
        string_cookie = os.environ.get(u"HTTP_COOKIE", u"")
        cookie = Cookie.SimpleCookie()
        self.session_id = None
        
        if string_cookie != "":
            cookie.load(string_cookie)
            # find our session id
            self.session_id = cookie.get(self.COOKIE_NAME).value
        
        user = users.get_current_user()
        send_cookie = False
        if self.session_id is None:
            # no session id in the cookie header so start a new empty session
            self.session_data = SessionData(data="", user=user)
            self.session_data.put()
            self.session_id = str(self.session_data.key())
            send_cookie = True
        else:
            # try to load SessionData object
            self.session_data = SessionData.get(self.session_id)
            
            # check that session user is the same as current user
            if self.session_data is None or self.session_data.user != user:
                # create new session and forget current one
                self.session_data = SessionData(data="", user=user)
                self.session_data.put()
                self.session_id = str(self.session_data.key())
                send_cookie = True
        
        if send_cookie:
            # put http session header
            out_cookie = Cookie.SimpleCookie()
            out_cookie[self.COOKIE_NAME] = self.session_id
            print out_cookie.output()
            
    def store(self, name, value):
        """
        Store a new value in the session
        """
        if name == "user":
            raise SessionNameError("Invalid value name: %s" % name)
        
        # store in the session data
        self.session_data.__setattr__(name, value)
        self.session_data.put()

        # and remember in memcache
        memcache.set(name, value, time=self.MEMCACHE_STORE_TIME, namespace=self.session_id)
    
    def fetch(self, name):
        """
        Fetch value from the session store: first try to fetch from the memcache, then from the storage
        """
        if name == "user":
            raise SessionNameError("Invalid value name: %s" % name)
        
        value = None
        value = memcache.get(name, self.session_id)
        if value is None:
            # try to fetch from the session data object
            try:
                value = self.session_data.__getattr__(name)
                memcache.set(name, value, time=self.MEMCACHE_STORE_TIME, namespace=self.session_id)
            except AttributeError:
                raise SessionValueNotFoundError
                
        return value
        
    def forget(self, name):
        """
        Forget session value, delete from store and from the memcache
        """
        memcache.delete(name, namespace=self.session_id)
        self.session_data.__delattr__(name)
        self.session_data.put()